package com.gzh.library

import android.app.IntentService
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import com.gzh.library.StorageUtils.getCacheDirectory
import com.gzh.library.util.CfuConstant
import com.gzh.library.util.CfuPublicUtil
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.net.HttpURLConnection
import java.net.URL

class DownloadService : IntentService("DownloadService") {
    private var mNotifyManager: NotificationManager? = null
    private var mBuilder: NotificationCompat.Builder? = null

    companion object {
        private const val BUFFER_SIZE = 10 * 1024
        private const val TAG = "DownloadService"
        var onProgressChangeListener: OnProgressChangeListener? = null
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        val builder = NotificationCompat.Builder(this, "cfu_download")
        val appName = getString(applicationInfo.labelRes)
        builder.setContentTitle(appName + "正在下载最新版本")
        //兼容5.0通知图标
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //如果自定义通知图标不存在则使用applogo
            if (CfuPublicUtil.isNotifyIconExsit(this) == 0) {
                builder.setSmallIcon(R.mipmap.ic_launcher)
            } else {
                builder.setSmallIcon(CfuPublicUtil.isNotifyIconExsit(this))
            }
        } else {
            builder.setSmallIcon(R.mipmap.ic_launcher)
        }
        builder.setAutoCancel(true)
        val notification = builder.build()
        startForeground(1, notification)
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onHandleIntent(intent: Intent?) {
        mNotifyManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        mBuilder = NotificationCompat.Builder(this, "cfu_download")
        val appName = getString(applicationInfo.labelRes)
        mBuilder?.setContentTitle(appName)?.setTicker("正在下载更新")
        //兼容5.0通知图标
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //如果自定义通知图标不存在则使用applogo
            if (CfuPublicUtil.isNotifyIconExsit(this) == 0) {
                mBuilder?.setSmallIcon(R.mipmap.ic_launcher)
            } else {
                mBuilder?.setSmallIcon(CfuPublicUtil.isNotifyIconExsit(this))
            }
        } else {
            mBuilder?.setSmallIcon(R.mipmap.ic_launcher)
        }
        // 通知不可清除
        mBuilder?.setAutoCancel(true)
        val urlStr = intent?.getStringExtra(CfuConstant.APK_DOWNLOAD_URL)
        var `in`: InputStream? = null
        var out: FileOutputStream? = null
        try {
            val url = URL(urlStr)
            val urlConnection = url.openConnection() as HttpURLConnection
            urlConnection.requestMethod = "GET"
            urlConnection.doOutput = false
            urlConnection.connectTimeout = 10 * 1000
            urlConnection.readTimeout = 10 * 1000
            urlConnection.setRequestProperty("Connection", "Keep-Alive")
            urlConnection.setRequestProperty("Charset", "UTF-8")
            urlConnection.setRequestProperty("Accept-Encoding", "gzip, deflate")
            urlConnection.connect()
            var bytetotal: Long = 0
            if (urlConnection.responseCode == 200) {
                bytetotal = urlConnection.contentLength.toLong()
            }
            var bytesum: Long = 0
            var byteread: Int
            `in` = urlConnection.inputStream
            val dir = getCacheDirectory(this)
            val apkName = urlStr?.substring(urlStr.lastIndexOf("/") + 1)
            apkName?.let {
                val apkFile = File(dir, apkName)
                out = FileOutputStream(apkFile)
                val buffer = ByteArray(BUFFER_SIZE)
                var oldProgress = 0
                while (`in`.read(buffer).also { byteread = it } != -1) {
                    bytesum += byteread.toLong()
                    out?.write(buffer, 0, byteread)
                    val progress = (bytesum * 100L / bytetotal).toInt()
                    // 如果进度与之前进度相等，则不更新，如果更新太频繁，会造成界面卡顿
                    if (progress != oldProgress) {
                        onProgressChangeListener?.onProgressChange(progress)
                        updateProgress(progress)
                    }
                    oldProgress = progress
                }
                // 下载完成
                mBuilder?.setContentText(getString(R.string.cfu_download_success))
                    ?.setProgress(0, 0, false)
                mNotifyManager?.cancelAll()
                // 安装APK包
                installApk(apkFile)
            }
        } catch (e: Exception) {
            Log.e(TAG, "download apk file error >>>> $e")
        } finally {
            if (out != null) {
                try {
                    out?.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            if (`in` != null) {
                try {
                    `in`.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 更新通知栏下载进度
     */
    private fun updateProgress(progress: Int) {
        // "正在下载:" + progress + "%"
        Log.e("下载", "正在下载:$progress%")
        mBuilder?.setContentText(this.getString(R.string.cfu_download_progress, progress))
            ?.setProgress(100, progress, false)
        val pendingintent = PendingIntent.getActivity(
            this, 0, Intent(), PendingIntent.FLAG_CANCEL_CURRENT
        )
        mBuilder?.setContentIntent(pendingintent)
        mNotifyManager?.notify(0, mBuilder?.build())
    }

    interface OnProgressChangeListener {
        fun onProgressChange(progress: Int)
    }

    /**
     * 安装应用
     */
    private fun installApk(apk: File) {
        val installAPKIntent = Intent(Intent.ACTION_VIEW)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            installAPKIntent.flags =
                Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK
            val apkUri = CfuPublicUtil.getFileUri(applicationContext, apk)
            installAPKIntent.setDataAndType(apkUri, "application/vnd.android.package-archive")
        } else {
            installAPKIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            installAPKIntent.setDataAndType(
                CfuPublicUtil.getFileUri(applicationContext, apk),
                "application/vnd.android.package-archive"
            )
        }
        val pendingIntent = PendingIntent.getActivity(
            this, 0, installAPKIntent, PendingIntent.FLAG_UPDATE_CURRENT
        )
        mBuilder?.setContentIntent(pendingIntent)
        val noti = mBuilder?.build()
        noti?.flags = Notification.FLAG_AUTO_CANCEL
        mNotifyManager?.notify(0, noti)

        // 跳转
        startActivity(installAPKIntent)
        CfuConstant.IS_UPDATEDIALOG_SHOW = false
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(true)
    }
}